package com.topscomm.meet.job;


import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.tencentcloudapi.wemeet.common.constants.InstanceEnum;
import com.tencentcloudapi.wemeet.common.constants.RestErrorCode;
import com.tencentcloudapi.wemeet.common.exception.WemeetSdkException;
import com.tencentcloudapi.wemeet.models.MeetingSetting;
import com.tencentcloudapi.wemeet.models.meeting.MeetingInfo;
import com.tencentcloudapi.wemeet.models.meeting.ModifyMeetingRequest;
import com.tencentcloudapi.wemeet.models.meeting.QueryMeetingDetailResponse;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.meet.MeetSystemConst;
import com.topscomm.meet.pojo.MeetRoomApplyEntity;
import com.topscomm.meet.service.impl.MeetRoomApplyService;
import com.topscomm.meet.service.impl.MeetRoomManageService;
import com.topscomm.meet.utils.TencentMeetUtil;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@JobHandler("remoteMeetOpenJob")
@Component
public class RemoteMeetOpenJob extends IJobHandler {
    @Autowired
    MeetRoomManageService meetRoomManageService;
    @Autowired
    MeetRoomApplyService meetRoomApplyService;


    /**
     * 开会前30分钟，将会议设置为允许在主持人进入之前进入，开放会议
     *
     * @param
     * @return
     * @author xinfushuo
     * @date 2023/4/7
     * @modify
     */
    @Override
    public ReturnT<String> execute(String param) {
        try {
            final DateTime now = DateTime.now().setMutable(false);
            //查询所有有效的线上会议室申请  获取MeetInfo list
            StringBufferProxy sql = new StringBufferProxy();
            sql.appendSingle("{0} IS NOT NULL AND '{1}' = (SELECT TYPE FROM MEETROOMMANAGE m2 WHERE m2.ID = {2}) AND BEGINTIME > SYSDATE ", MeetRoomApplyEntity.FieldRemotemeetinfo, MeetSystemConst.MeetRoomTypeEnum.Remote, MeetRoomApplyEntity.FieldMeetroomid);
            List<MeetRoomApplyEntity> applyEntities = this.meetRoomApplyService.queryByWhere(sql.toString()).stream().filter(m -> JSONUtil.isJson(m.getRemotemeetinfo())).collect(Collectors.toList());
            List<MeetingInfo> meetingInfos = new ArrayList<>();
            //获取会议信息
            applyEntities.forEach(apply -> {
                MeetingInfo applyMeetInfo = JSONUtil.toBean(apply.getRemotemeetinfo(), MeetingInfo.class);
                //定义时间戳差值
                long timeDifference = Long.parseLong(applyMeetInfo.getStartTime()) - now.getTime() / 1000;
//              若当前时间与待开会议的会议信息10位开始时间时间戳差距30分钟以内且不为负值，且设置为不允许用户提前进入，进行设置更新 允许用户提前进入
                if(! (timeDifference >= 0 && timeDifference < 30 * 60 && applyMeetInfo.getSettings().getAllowInBeforeHost() != Boolean.TRUE)){
                    return;
                }
                ModifyMeetingRequest modifyMeetingRequest = new ModifyMeetingRequest();
                modifyMeetingRequest.setMeetingId(applyMeetInfo.getMeetingId());
                modifyMeetingRequest.setInstanceId(InstanceEnum.INSTANCE_PC.getInstanceID());
                //复制设置并修改
                modifyMeetingRequest.setSettings(applyMeetInfo.getSettings() == null ? new MeetingSetting() : applyMeetInfo.getSettings());
                modifyMeetingRequest.getSettings().setAllowInBeforeHost(Boolean.TRUE);
                modifyMeetingRequest.setUserId(meetRoomApplyService.getUserid(ConvertUtil.convertToString(apply.getMeetroomid())));
                try {
                    QueryMeetingDetailResponse response = TencentMeetUtil.MEETING_CLIENT.modifyMeeting(modifyMeetingRequest);
                    log.info(JSONUtil.toJsonPrettyStr(response.getMeetingInfoList().get(0)));
                    //获取最新会议信息并更新
                    //将会议信息转换为json 不忽略null值
                    String info = JSONObject.toJSONString(applyMeetInfo, SerializerFeature.WriteMapNullValue);
                    apply.setRemotemeetinfo(info);
                } catch (WemeetSdkException e) {
                    if (e.getCode() == Integer.parseInt(RestErrorCode.MEET_CANCELED)) {
                        return;
                    }
                    updateRemoteInfo(applyEntities);
                    throw new ServiceException("modify fail," + JSONUtil.toJsonPrettyStr(applyMeetInfo));
                }
            });
            updateRemoteInfo(applyEntities);
        } catch (Exception e) {
            log.error("执行完毕,修改会议信息失败", e);
            return new ReturnT<>(500, "job failed , modify meet info failed.\n"+ ExceptionUtils.getStackTrace(e).substring(0,2000));
        }
        //更新结果
        return new ReturnT<>(200, "modify meet info success");
    }

    /**
     * 更新本地会议室申请记录的远程会议信息字段
     *
     * @param roomApplyEntities 会议室申请列表
     * @author xinfushuo
     * @date 2023/4/11
     * @modify
     */
    private void updateRemoteInfo(List<MeetRoomApplyEntity> roomApplyEntities) {
        //构造maplist 用于批量更新 申请id 会议信息
        List<Map<String, Object>> mapList = roomApplyEntities.stream().map(apply -> {
            Map<String, Object> map = new HashMap<>();
            map.put(MeetRoomApplyEntity.FieldId, apply.getId());
            map.put(MeetRoomApplyEntity.FieldRemotemeetinfo, apply.getRemotemeetinfo());
            return map;
        }).collect(Collectors.toList());
        this.meetRoomApplyService.updateBatchMap(mapList);
    }
}
